package com.tron.task.tron;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tron.context.RedisContext;
import com.tron.entity.PayOrder;
import com.tron.entity.TronAccount;
import com.tron.service.PayOrderService;
import com.tron.service.TronAccountService;
import com.tron.utils.tron.TronAddress;
import com.tron.utils.tron.TronUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;

/**
 * 订单监听 - 传入一个账户account
 */
@Slf4j
@Component
public class OrderListener extends QuartzJobBean {
    @Resource
    private TronUtils tronUtils;

    @Autowired
    private RedisContext redisContext;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private Scheduler scheduler;

    @Autowired
    private PayOrderService payOrderService;

    @Autowired
    private TronAccountService tronAccountService;

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        String account = (String)jobDataMap.get("address");
        String privateKey = (String)jobDataMap.get("privateKey");
        String jobName = (String)jobDataMap.get("jobName");

        PayOrder payOrder = null;

        //tronUtils.checkIfTronAddressTrue(account);

        //取数据 - 判断有没有过期
        String payKey = redisContext.getOrderPayKey(account);
        Object o = redisTemplate.opsForValue().get(payKey);
        if(Objects.isNull(o)){
            log.info("订单失败!----->>@!");
            saveReuseAccount(account,privateKey);
            // 关闭定时任务
            stopTask(jobName); //关闭线程
            return;
        }

        //有数据处理业务
        try {
            payOrder = (PayOrder) o;
            if(Objects.nonNull(payOrder.getAddress())){
                Long aLong = tronUtils.searchTrcBalance(payOrder.getAddress(), payOrder.getPrivateKey());
                //log.info("比较金额---->>"+aLong+"||"+ payOrder.getAmount());
                //1TRX = 1000000
                if(aLong >= payOrder.getAmount() * 1000000){
                    this.orderCompletion(payOrder,jobName);

                    return;
                }else{
                    log.info("等待支付----->> "+payOrder.getAddress()+" 当前余额:" +aLong);
                }
            }
        } catch (Exception e){
            log.error("Order对象转换失败！！");
            saveReuseAccount(account,privateKey);
            stopTask(jobName);
        }
    }

    /**
     * 关闭定时任务
     */
    public void stopTask(String jobName){
	    JobKey jobKey = JobKey.jobKey(jobName);
        try {
            scheduler.deleteJob(jobKey);
        } catch (SchedulerException e) {
            System.out.println("删除定时任务出错："+e.getMessage());
        }
    }

    /**
     * 订单完成的调用
     */
    public void orderCompletion(PayOrder payOrder, String jobName) {
        //返回数据
        log.info("完成订单!----->>" + payOrder.getAmount());

        //更新订单表
        PayOrder payOrderUpdate = payOrderService.getById(payOrder.getId());
        payOrderUpdate.setStatus(1); //状态设为已完成
        payOrderService.updateById(payOrderUpdate);

        //查询账户表
        TronAccount tronAccount= tronAccountService.getOne(new LambdaQueryWrapper<TronAccount>()
                .eq(TronAccount::getAddress,payOrder.getAddress())
                .eq(TronAccount::getPrivateKey,payOrder.getPrivateKey())
                .last("limit 1")
        );

        tronAccount.setIsOrderFlow(0); //设置没有走流程
        tronAccount.setIsReuse(0); //设置不可复用
        tronAccountService.updateById(tronAccount); //更新账户表

        //调用回调地址.....
        String accountReuseKey = redisContext.getAccountReuse(payOrder.getAddress());
        redisTemplate.delete(accountReuseKey);//移除key
        stopTask(jobName); //关闭线程
    }


    public void saveReuseAccount(String address,String privateKey){
        Long aLong = tronUtils.searchTrcBalance(address, privateKey);
        LambdaQueryWrapper<TronAccount> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TronAccount::getAddress,address);
        wrapper.last("limit 1");
        TronAccount account = tronAccountService.getOne(wrapper);
        account.setIsReuse(1);
        account.setIsOrderFlow(0);
        account.setBalance(aLong);
        tronAccountService.updateById(account);
    }
}
